package nl.ViewerServer.ServerManager.JobManager.Strategy;

import nl.ViewerServer.Application;
import nl.ViewerServer.ServerManager.ServerManager;
import nl.ViewerServer.ServerManager.JobManager.ParaViewThreadAssignment;

import org.apache.log4j.Logger;

public class DefaultStrategy implements AssignmentStrategy {
   private static Logger            log                      = Logger.getLogger( DefaultStrategy.class );
   
   private int paraviewThreadsTaken = 0;
   private int totalParaviewThreads = Application.config.paraviewThreadCount;

   public ParaViewThreadAssignment assignParaViewThreads( int requestedThreads ) {
      // a worker asks how many paraview threads it is allowed to start
      if( paraviewThreadsTaken >= totalParaviewThreads )
         return null;

      // current strategy: give the worker half of the available threads, but never allow
      // leaving less paraview threads than there can be additional workers in the pool

      int amount = totalParaviewThreads;
      // try to suit the needs of the client
      if( requestedThreads > 0 )
         amount = requestedThreads;

      // but still enforce the rules of the strategy
      amount = Math.min( amount, ( totalParaviewThreads - paraviewThreadsTaken ) / 2 );
      amount = Math.min( amount, Application.config.maxParaviewThreadCountPerWorker );
      
      int poolThreadsLeft = Application.config.poolSize - ServerManager.jobManager.getActiveCount();
      amount = Math.min( totalParaviewThreads - paraviewThreadsTaken - poolThreadsLeft, amount );

      paraviewThreadsTaken += amount;
      log.info( "Worker gets " + amount + " threads, " + ( totalParaviewThreads - paraviewThreadsTaken ) + " available" );

      return new ParaViewThreadAssignment( amount, Application.config.MPIMachineFile );

   }

   public void reclaimParaviewThreadAssignment( ParaViewThreadAssignment assignment ) {
      paraviewThreadsTaken -= assignment.totalThreadCount;
   }

}
